package org.softee.extractor.sax.helper;

import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;

import org.softee.extractor.helper.Logger;

public class NsBindings {
    private static final Logger logger = new Logger(NsBindings.class);
    private static final String COLON = ":";
    private final Deque<NsBinding> bindings = new LinkedList<NsBinding>();
    private final NsBindings parent;


    public NsBindings() {
        this(null);
    }

    public NsBindings(NsBindings parent) {
        this.parent = parent;
    }

    public static String extractPrefix(String qName) {
        int pos = qName.indexOf(COLON);
        return (pos == -1) ? "" : qName.substring(0, pos);
    }

    public NsBinding getNsBinding(String prefix) {
        Iterator<NsBinding> iterator = bindings.descendingIterator();
        while (iterator.hasNext()) {
            NsBinding binding = iterator.next();
            if (binding.getPrefix().equals(prefix)) {
                logger.log("Resolving prefix binding %s", binding);
                return binding;
            }
        }
        if (parent == null) {
            logger.log("No bindings for '%s'", prefix);
            return null;
        }
        // no mapping found in current context, ask parent
        return parent.getNsBinding(prefix);
    }

    public void startPrefixMapping(NsBinding binding) {
        logger.log("Start prefix mapping for %s in %s", binding, this);
        bindings.addLast(binding);
    }

    public boolean endPrefixMapping(String prefix) {
        logger.log("End prefixmapping for '%s' in %s", prefix, bindings);
        Iterator<NsBinding> iterator = bindings.descendingIterator();
        while (iterator.hasNext()) {
            NsBinding binding = iterator.next();
            if (binding.getPrefix().equals(prefix)) {
                iterator.remove();
                return true;
            }
        }
        logger.log("Unable to end prefix mapping for '%s' in %s", prefix, bindings);
        return false;
    }

    public NsBindings getParent() {
        return parent;
    }

    @Override
    public String toString() {
        if (parent == null) {
            return bindings.toString();
        } else {
            return bindings.toString() + ", " + parent.toString();
        }
    }

}
